package com.danco.training.zaneuskaya.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.danco.training.zaneuskaya.domain.Forum;
import com.danco.training.zaneuskaya.domain.Note;
import com.danco.training.zaneuskaya.domain.User;
import com.danco.training.zaneuskaya.repository.ForumDao;
import com.danco.training.zaneuskaya.repository.NoteDao;
import com.danco.training.zaneuskaya.repository.UserDao;
import com.danco.training.zaneuskaya.service.ForumService;
/**
 * @author Zaneuskaya Aliaksandra
 *
 */
@Service("forumService")
@Transactional
public class ForumServiceImpl implements ForumService {

	private static final String FORUM_NOT_FOUND = "Forum not found";

	private static final Logger logger = Logger
			.getLogger(ForumServiceImpl.class);

	@Autowired
	private ForumDao forumDao;

	@Autowired
	private UserDao userDao;

	@Autowired
	private NoteDao noteDao;

	public NoteDao getNoteDao() {
		return noteDao;
	}

	public void setNoteDao(NoteDao noteDao) {
		this.noteDao = noteDao;
	}

	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	public ForumDao getForumDao() {
		return forumDao;
	}

	public void setForumDao(ForumDao forumDao) {
		this.forumDao = forumDao;
	}

	@Override
	public void createEntity(Forum t) {
		try {

			forumDao.create(t);

		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}

	}

	@Override
	public void deleteEntityById(Integer id) {
		try {
			Forum forum = forumDao.read(id);
			forumDao.delete(forum);
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}

	}

	@Override
	public void updateEntity(Forum t) {
		try {
			Forum forum = forumDao.read(t.getForumId());
			forum.setForumTitle(t.getForumTitle());
			forum.setAdministrator(t.getAdministrator());
			forum.setEnableReading(t.isEnableReading());
			forum.setEnableWriting(t.isEnableWriting());
			forum.setForumDescription(t.getForumDescription());
			forum.setForumNotes(t.getForumNotes());
			forum.setMembers(t.getMembers());
			forumDao.update(forum);
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}

	}

	@Override
	public Forum getEntityById(Integer id) {
		Forum forum = null;
		try {
			forum = forumDao.read(id);
			if (forum == null) {
				throw new NullPointerException(FORUM_NOT_FOUND);
			}
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}
		return forum;
	}

	@Override
	public List<Forum> getEntityList() {
		List<Forum> forums = null;
		try {
			forums = forumDao.readAll();
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}
		return forums;
	}

	@Override
	public List<Forum> getForumListByTitle(String title) {
		List<Forum> forums = null;
		try {
			forums = forumDao.findForumsByTitle(title);
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}
		return forums;
	}

	@Override
	public List<Forum> getUserForumList(User user) {
		List<Forum> forums = null;
		try {
			user = userDao.read(user.getUserId());
			forums = new ArrayList<Forum>(user.getForums());
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}
		return forums;

	}

	@Override
	public void addForumMember(Forum forum, User user) {
		try {
			forum = forumDao.read(forum.getForumId());
			user = userDao.read(user.getUserId());
			forum.getMembers().add(user);
			forumDao.update(forum);
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}

	}

	@Override
	public void deleteMemberFromForum(Forum forum, User user) {
		try {
			forum = forumDao.read(forum.getForumId());
			user = userDao.read(user.getUserId());

			forum.getMembers().remove(user);
			forumDao.update(forum);
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}

	}

	@Override
	public void addForumNote(Forum forum, Note note) {
		try {

			forum = forumDao.read(forum.getForumId());
			note = noteDao.read(note.getNoteId());

			forum.getForumNotes().add(note);
			forumDao.update(forum);
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}

	}

	@Override
	public void deleteForumNote(Forum forum, Note note) {
		try {
			forum = forumDao.read(forum.getForumId());
			note = noteDao.read(note.getNoteId());

			forum.getForumNotes().remove(note);
			forumDao.update(forum);
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}

	}

	@Override
	public boolean isMember(Forum forum, User user) {
		try {
			forum = forumDao.read(forum.getForumId());
			user = userDao.read(user.getUserId());
			if (forum == null || user == null) {
				throw new NullPointerException();
			} else {
				return forum.getMembers().contains(user);
			}
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}
		return false;

	}

}
